/**
 * Copyright 2006 gworks.com.au
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. (http://www.apache.org/licenses/LICENSE-2.0)
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed 
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 
 * the specific language governing permissions and limitations under the License.
 *
 * <dhamma-message src="Atisha (11th century Tibetan Buddhist master)">
 * 	The greatest achievement is selflessness. The greatest worth is self-mastery.
 * 	The greatest quality is seeking to serve others. The greatest precept is continual awareness.
 * 	The greatest medicine is the emptiness of everything. The greatest action is not conforming with the worlds ways.
 * 	The greatest magic is transmuting the passions. The greatest generosity is non-attachment.
 * 	The greatest goodness is a peaceful mind. The greatest patience is humility.
 * 	The greatest effort is not concerned with results. The greatest meditation is a mind that lets go.
 * 	The greatest wisdom is seeing through appearances. 
 * </dhamma-message>
 */
package org.javaongems.client.rt.text.dom;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;

/**
 * <p>Provide extension utilities for the GWT DOM class.</p>
 * <p>Responsibilities:
 * <ul>
 * 	<li> expose reusable functionality that is otherwise hidden inside 
 * 		the DOM class and only accessible by adding to that namespace
 *  <li> provide features that are DOM specific and are currently not
 *  	service by the DOM class  
 * </ul>
 * </p>
 * <p>Collaborators:
 * <ul>
 * 	<li> DOM
 *  <li> JSNI javascript
 * </ul>
 * </p>
 * <p>Considerations:
 * <ul>
 * 	<li> This class violates my principle of having no component having in excess
 * 		of 20% JSNI code
 * 	<li> This force can be reduced if and only if each jsni method is small and 
 * 		regularly returns control back to java code 
 * </ul>
 * </p>
 * 
 * @author Ashin Wimalajeewa (ash)
 */
public class DomExtUtils {
	static public Element getEventTargetTag(Event event, Element containerElem, String tagName) {
		Element tag = DOM.eventGetTarget(event);
		while (!DOM.getAttribute(tag, "tagName").equalsIgnoreCase(tagName)) {
			if ((tag == null) || DOM.compare(tag, containerElem))
				return null;
			tag = DOM.getParent(tag);
		}
		return tag;
	}
	
	static public Element createAndAppendElement(Element parent, String tag) {
		Element ret = DOM.createElement(tag);
		DOM.appendChild(parent, ret);
		return ret;
	}

	native static public void setElementZindex(Element elem, int idx) /*-{
		elem.style.zIndex = idx;
	}-*/;

	native static public Element getDocumentFromFrame(Element frame) /*-{
	    var doc = null;
	    if (frame.contentWindow) {
	      doc = frame.contentWindow.document;
	    }
	    return doc ? doc: null;
	}-*/;
	
	native static public Element getElementByIdFromFrame(Element frame, String id) /*-{
	    var tokenElement = null;
	    if (frame.contentWindow) {
	      var doc = frame.contentWindow.document;
	      tokenElement = doc ? doc.getElementById(id) : null;
	    }
	    return tokenElement
	}-*/;
	
	native static public Element cloneNode(Element elem, boolean subtree) /*-{
		return elem.cloneNode(subtree);
	}-*/; 
	
    native static public void submitForm(Element elem) /*-{
    	elem.submit();
    }-*/;	

	native static public void setAttribute(Element elem, String name, String val) /*-{
		elem.setAttribute(name, val);
	}-*/;
    
	native static public void setNameAttribute(Element elem, String val) /*-{
		elem.name = val;
	}-*/;

	native static public void setNameAttribute(Element parent, int child, String val) /*-{
		parent[child].name = val;
	}-*/;

	native static public Element prepareInputHidden(String nm, String val) /*-{
		var ret = $doc.createElement("input");
		ret.type = "hidden";
		ret.value = "" + val + "";
		ret.name = "" + nm + "";
		return ret;
	}-*/;
	
	native static public void removeAttribute(Element elem, String attr) /*-{
		elem.removeAttribute(attr);
	}-*/;
	
	native static public int getOffsetLeft(Element elem) /*-{
		 var left = 0;
		 if (elem) 
		 	left = elem.offsetLeft;
		 return left;
	 }-*/;

	native static public int getOffsetTop(Element elem) /*-{
		 var top = 0;
		 if (elem) 
		 	top = elem.offsetTop;
		 return top;
    }-*/;
	
	native static public void setOffsetLeft(Element elem, int left) /*-{
		 elem.offsetLeft = left;
	 }-*/;

	native static public void setOffsetTop(Element elem, int top) /*-{
	 	elem.offsetTop = top;
	 }-*/;
}